package com.java3_8;

import java.security.spec.RSAOtherPrimeInfo;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class java3_8 {
    //    public static void main(String[] args) {
//
//        List list = Arrays.asList(12, 23, 34, 45, 56, 67, 78, 89, 90);
//        List list1 = Collections.synchronizedList(list);
//        list1.add(123);
//        List list1 = Collections.unmodifiableList(list);
//        list1.add(123);
//        List listDest = Arrays.asList(new Object[listSrc.size()]);
//        Collections.copy(listDest, listSrc);
    //    }
//    public static void main(String[] args) {
//        //异常是什么  --  java.lang.Throwable中 （error 、 Exception）
//
//        //异常的作用：
//        //（1）提供错误信息
//        //（2）抛出异常
//
////        try {
////            Student student = null;
////            System.out.println(student.getAge()); //NullPointerException
////        } catch (NullPointerException e) {
////            String message = e.toString();
////            System.out.println(message);
////        }
////        System.out.println("异常处理完毕");
//
////        try{
////            int a = 10;
////            int b = 0;
////            System.out.println(a/b); //ArithmeticException
////        }catch (ArithmeticException e){
////            System.out.println(e.getMessage());
////        }
////        System.out.println("异常处理完毕");
//
////        try {
////            int[] arr = {1, 2, 3, 4, 5};
////            for (int i = 0; i <= arr.length; i++) {
////                System.out.print(arr[i] + " ");
////            }
////        } catch (ArrayIndexOutOfBoundsException e) {
////            e.printStackTrace();
////        } catch (Exception e){
////            e.printStackTrace();
////        }
////        System.out.println("异常处理完毕");
//
//        //异常的三种处理方式
//        //（1）JVM处理
////        int[] arr = new int[5];
////        Arrays.fill(arr,100);
////        for (int i = 0; i < arr.length; i++) {
////            System.out.println(arr[i]);
////        }
////        System.out.println(arr[9]);
//        //直接报错
//
//        //(2)try-catch捕获异常
////        try {
////            int a = 10;
////            int b = 0;
////            System.out.println(a/b);
////            int[] arr = new int[5];
////            Arrays.fill(arr, 100);
////            for (int number : arr){
////                System.out.println(number);
////            }
////            Student student = null;
////            System.out.println(student.getAge());
////        } catch (ArithmeticException e) {
////            e.printStackTrace();
////        } catch (ArrayIndexOutOfBoundsException e){
////            e.printStackTrace();
////        } catch (NullPointerException e){
////            e.printStackTrace();
////        } catch (Exception e){
////            e.printStackTrace();
////        }
////        System.out.println("异常已经处理完毕");
//        //没有异常就直接全部执行
//        //一个异常拦截之后后面的代码就不会在执行了
//        //如果没有捕获就会报错（JVM）
//        //多个问题多个try-catch
//
//        //异常的三种方法
//        //(1)getMessage
//        //(2)toString
//        //(3)printStacktrace
//
//
//    }
//    public static void main(String[] args) {
////        //自定义异常类型
////        Scanner sc = new Scanner(System.in);
////        System.out.print("请输入一个整数: ");
////        int number = sc.nextInt();
////        int fun = 0;
////        try {
////            fun = Fun(number);
////        } catch (RuntimeException e) {
////            System.out.println(e.getMessage());
////        }
////        if (fun > 50) {
////            System.out.println("恭喜您，您的数字变成了" + fun);
////        }
////    }
////
////    public static int Fun(int number) {
////        if (number * 5 <= 50) {
////            throw new NumberException("您输入的数字过小");
////        }
////        return number * 5;
////    }
////      什么时候使用try-catch、throw
//        //（1）父类没有抛出异常 + 有必须执行的代码
//        //（2）统一处理 - throw
//
//
//
//    }
//    public static void main(String[] args) {
    //finally -- 有代码必须执行
//        try{
//            int[] arr = new int[5];
//            Arrays.fill(arr, 100);
//            System.out.println(arr[9]);
//        } catch (ArrayIndexOutOfBoundsException e){
//            System.out.println("您的数组索引越界了");
//            //System.out.println(10/0);
//            //直接停止JVM虚拟机运行 -- 使finally代码不运行
//            System.exit(0);
//        } finally {
//            //必须执行，即使报错
//            System.out.println("异常处理完毕");
//        }
//    public static void main(String[] args) {
//        try{
//            return;
//        } finally {
//            System.out.println("这是finally执行的代码");
//        }
    //先执行finally中的代码
    //
//        {
//            System.out.println("a");
//        };
//        static{
//            System.out.println("b");
//        };
//
//        public static String getOut(){
//            try{
//                return "1";
//            }catch(Exception e){
//                return "2";
//            }finally{
//                return "3";
//            }
//        }
//        public static void main(String[] args) {
//            System.out.println(getOut());
//
//    }//
//    public static void main(String[] args) {
//        //线程
//        //（1）继承Thread类创建线程
////        MyThread myThread = new MyThread("线程一");
////        myThread.start();
////        for (int i = 1; i <= 10; i++) {
////            System.out.println(Thread.currentThread().getName() + " " + i);
////        }
//
//        //(2)使用实现类创建线程
////        MyThread2 myThread2 = new MyThread2();
////        Thread thread = new Thread(myThread2,"线程2");
////        thread.start();
//
//        //(3)使用匿名内部类创建线程
//        //继承
////        Thread thread = new Thread() {
////            @Override
////            public void run() {
////                System.out.println("这是使用继承的匿名内部类创建的线程");
////            }
////        };
////        thread.start();
////
////        new Thread(new Runnable() {
////            @Override
////            public void run() {
////                System.out.println("这是使用匿名实现类内部类创建的线程");
////            }
////        }).start();
////
////        //run -- 都是实现的Runnable接口中的run方法
////        new Thread(){
////            @Override
////            public void run() {
////                System.out.println("This is a test !");
////            }
////        }.start();
//
//        //使用的run方法都是Thread里面的方法
//        //更推荐使用接口实现的方式创建线程
//
//
//        //线程中的构造器
//        /*
//        (1)Thread()
//        (2)Thread(String name)
//        (3)Thread(Runnable s)
//        (4)Thread(Runnable s, String name)
//        * */
////
////        MyThread3 myThread3 = new MyThread3("线程4");
////        myThread3.start();
//
////        new Thread(new Runnable() {
////            @Override
////            public void run() {
////                System.out.println(Thread.currentThread().getName()+"这是使用实现接口的方式创建的线程");
////            }
////        },"线程5").start();
//
////        new Thread(){
////            @Override
////            public void run() {
////                for (int i = 0; i < 10; i++) {
////                    System.out.println(i);
////                }
////            }
////        }.start();
//        //start -- 开始线程 + 调用run方法
//        //run -- 就是线程所要干的事情
//
////        MyThread3 myThread3 = new MyThread3("线程6");
////        myThread3.start();
//        //currentThread -- 静态方法，获取当前线程的对象
//
////        Thread thread = new Thread(new Runnable() {
////            @Override
////            public void run() {
////                for (int i = 0; i < 10; i++) {
////                    System.out.println(Thread.currentThread().getName() + i);
////                }
////            }
////        });
////        thread.setName("线程8");
////        System.out.println(thread.getName());
////        //get + set 方法对线程进行改变
////        thread.start();
//
//        //sleep
////        new Thread(){
////            @Override
////            public void run() {
////                for (int i = 0; i < 10; i++) {
////                    try {
////                        Thread.sleep(1000);
////                    } catch (InterruptedException e) {
////                        throw new RuntimeException(e);
////                    }
////                    System.out.println(i);
////                }
////            }
////        }.start();
//
////        new Thread() {
////            @Override
////            public void run() {
////                for (int i = 0; i < 100; i++) {
////                    if(i == 20){
////                        Thread.yield();
////                        //释放当前CPU的使用权
////                    }
////                    if(i == 50){
////
////                    }
////                    System.out.println(Thread.currentThread().getName() + " " + i);
////                }
////            }
////        }.start();
////        for (int i = 0; i < 100; i++) {
////            System.out.println(Thread.currentThread().getName() + " " + i);
////        }
//
////        MyThread3 myThread3 = new MyThread3("线程一");
////        myThread3.start();
////
////        for (int i = 0; i < 30; i++) {
////            if(i == 15)
////                myThread3.join();
////            System.out.println(Thread.currentThread().getName() + " " + i);
////        }
////    }
//
////        new Thread(){
////            @Override
////            public void run() {
////                for (int i = 0; i < 30; i++) {
////                  if(i == 15){
////                      System.out.println(this.isAlive());
////                  }
////                    System.out.println(i);
////                }
////            }
////        }.start();
//        //isAlive判断当前线程是否还运行着
//
//    }
//    public static void main(String[] args) {
////        MyThread3 myThread1 = new MyThread3("线程1");
////        MyThread3 myThread2 = new MyThread3("线程2");
////
////        //并不是优先级越高就先执行完毕
////        myThread1.setPriority(Thread.MAX_PRIORITY);
////        myThread2.setPriority(Thread.MIN_PRIORITY);
////
////        System.out.println(myThread2.getPriority());
////        System.out.println(myThread1.getPriority());
////
////        myThread2.start();
////        myThread1.start();
//
//        //多线程的声明周期
//        //守护线程 -- 当被守护的线程结束之后，守护线程会直接结束
////
////        DaemonThread daemonThread = new DaemonThread();
////        Thread thread = new Thread(daemonThread);
////        thread.setDaemon(true);
////        thread.start();
////        for (int i = 0; i < 30; i++) {
////            System.out.println(Thread.currentThread().getName() + " " + i);
////        }
//
//        //使用setDaemon使线程变成守护线程
//
//
//    }
//    public static void main(String[] args) {
//        //单例模式
////        Demo2 demo2 = Demo2.getDemo2();
////        System.out.println(demo2.toString());
//
//
//    }
//    public static void main(String[] args) {
////        Demo3 demo3 = Demo3.getDemo3();
////        System.out.println(demo3.toString());
//
////        Demo4 demo4 = Demo4.getDemo4();
////        System.out.println(demo4.toString());
//
////        Thread thread = new Thread() {
////            @Override
////            public void run() {
////                Demo4 demo4 = Demo4.getDemo4();
////                System.out.println(demo4.toString());
////            }
////        };
////        thread.start();
//
//        //死锁 -- 两个线程互相占用着对方所需要的锁，但是自己又不能完成线程释放锁
//
//        //Lock实现线程安全
//        /*
//        (1)创建ReentrantLock实现类的对象，使用private+static修饰
//        (2)使用lock+unlock使线程安全
//        * */
//
//        //补充：使用Callable创建线程
////
////        MyThread4 myThread4 = new MyThread4();
////        FutureTask futureTask = new FutureTask(myThread4);
////        Thread thread = new Thread(futureTask);
////        thread.start();
////
////
////        try {
////            System.out.println("所有数的总和为："+futureTask.get());
////        } catch (InterruptedException e) {
////            throw new RuntimeException(e);
////        } catch (ExecutionException e) {
////            throw new RuntimeException(e);
////        }
//
//        //Callable接口创建线程的好处
//        /*
//        * （1）可以抛出异常
//        * （2）可以又返回值
//        * */
//
////        MyThread5 myThread5 = new MyThread5();
////        Thread thread1 = new Thread(myThread5,"线程1");
////        Thread thread2 = new Thread(myThread5,"线程2");
////
////        thread1.start();
////        thread2.start();
//
////        TotalDish totalDish = new TotalDish(0);
////
////        //创造了两个实现类 + 并且将共享数据当成参数传入
////        ThreadPut threadPut = new ThreadPut(totalDish);
////        ThreadTake threadTake = new ThreadTake(totalDish);
////
////        Thread threadPut1 = new Thread(threadPut);
////        Thread threadPut2 = new Thread(threadPut);
////        Thread threadPut3 = new Thread(threadPut);
////
////        Thread threadTake1 = new Thread(threadTake);
////        Thread threadTake2 = new Thread(threadTake);
////        Thread threadTake3 = new Thread(threadTake);
////
////        threadPut1.start();
////        threadPut2.start();
////        threadPut3.start();
////
////        threadTake1.start();
////        threadTake2.start();
////        threadTake3.start();
//
//    }
    public static void main(String[] args) {
        Dish dish = new Dish(0);
        new Thread("厨师1"){
            @Override
            public void run() {
                while (true) {
                    dish.addDish();
                }
            }
        }.start();
        new Thread("厨师2"){
            @Override
            public void run() {
                while (true) {
                    dish.addDish();
                }
            }
        }.start();
        new Thread("服务员1"){
            @Override
            public void run() {
                while (true) {
                    dish.delDish();
                }
            }
        }.start();
        new Thread("服务员2"){
            @Override
            public void run() {
                while (true) {
                    dish.delDish();
                }
            }
        }.start();

    }

}
